﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;

using Robert.TwitBy.Properties;
using Robert.TwitBy.Views;

using TweetSharp.Twitter.Extensions;
using TweetSharp.Twitter.Fluent;
using TweetSharp.Twitter.Model;
using TweetSharp.Model;

namespace Robert.TwitBy.ViewModels
{
    public class LoginViewModel : MainViewModel
    {
        public LoginViewModel(Dispatcher dispatcher, MainViewModel model, TwitterViewModel tmodel) :
            base(dispatcher, model)
        {
            _dispatcher = dispatcher;
            _model = model;
            _tmodel = tmodel;

            this.AuthenticateCommand = new RelayCommand(p => new Action(()=>this.Authenticate()).BeginInvoke(null,null), p => this.CanAuthenticate());
            this.GetPinCommand = new RelayCommand(p => new Action(() => this.GetPin()).BeginInvoke(null, null));

            this.InputBindings = new List<InputBinding>();
            this.InputBindings.Add(new KeyBinding(this.AuthenticateCommand, new KeyGesture(Key.Enter)));
        }
        

        private string _pin;
        private string _consumerKey = Settings.Default.ConsumerKey;
        private string _consumerSecret = Settings.Default.ConsumerSecret;
        private string _accessToken = Settings.Default.AccessToken;
        private string _accessSecret = Settings.Default.AccessTokenSecret;
        private OAuthToken _requestToken;
        private Dispatcher _dispatcher;
        private string _pinText = "";
        private MainViewModel _model;
        private TwitterViewModel _tmodel;

        public string Pin
        {
            get { return _pin; }
            set { _pin = value.Trim(); OnPropertyChanged("Pin"); }
        }

        public string PinText
        {
            get { return _pinText; }
            set { _pinText = value; OnPropertyChanged("PinText"); }
        }

        public ICommand GetPinCommand { get; private set; }
        public ICommand AuthenticateCommand { get; private set; }

        public IList<InputBinding> InputBindings { get; private set; }

        private void GetPin()
        {
            PinText = "Sending authentication to Twitter.";

            var requestToken = FluentTwitter.CreateRequest()
                .Authentication
                .GetRequestToken(_consumerKey, _consumerSecret);

            var response = requestToken.Request();

            var result = response.AsToken();

            _dispatcher.BeginInvoke(new Action(() =>
            {
                if (result != null) _requestToken = result;
                
                FluentTwitter.CreateRequest()
                    .Authentication
                    .AuthorizeDesktop(_consumerKey, _consumerSecret, _requestToken.Token);

                PinText = "Succes.";
            }));
        }

        private void Authenticate()
        {
            if (string.IsNullOrEmpty(Pin))
            {
                MessageBox.Show("Pin cannot be empty.");
                return;
            }

            PinText = "Verifying credentials.";

            var accessToken = FluentTwitter.CreateRequest()
                .Authentication
                .GetAccessToken(_consumerKey, _consumerSecret, _requestToken.Token, Pin);

            var response = accessToken.Request();

            var result = response.AsToken();

            if (result == null || string.IsNullOrEmpty(result.Token))
            {
                var error = response.AsError();
                MessageBox.Show(error.ErrorMessage);
                return;
            }

            Settings.Default.AccessToken = result.Token;
            Settings.Default.AccessTokenSecret = result.TokenSecret;
            Settings.Default.Save();

            var verify = FluentTwitter.CreateRequest()
                .AuthenticateWith(_consumerKey, _consumerSecret, result.Token, result.TokenSecret)
                .Account()
                .VerifyCredentials();

            response = verify.Request();

            var getFollowers = FluentTwitter.CreateRequest()
                .AuthenticateWith(_consumerKey, _consumerSecret, result.Token, result.TokenSecret)
                .Users().GetFollowers().AsJson();

            var user = response.AsUser();

            response = getFollowers.Request();

            var users = response.AsUsers();

            if (user != null && users != null)
            {
                Settings.Default.UserId = user.ScreenName;
                Settings.Default.Followers = new System.Collections.Specialized.StringCollection();
                foreach (var us in users)
                    Settings.Default.Followers.Add(us.ScreenName);
                Settings.Default.Save();
            }
            else
            {
                PinText = "Ups. Something went wrong. Please restart.";
                return;
            }

            _dispatcher.BeginInvoke(
                new Action(
                    () =>
                    {
                        _model.GoToTweets(_tmodel);
                    }
                            )
                            );
        }

        [DebuggerStepThrough]
        private bool CanAuthenticate()
        {
            if (string.IsNullOrEmpty(Pin) || _requestToken == null)
                return false;
            else
                return true;
        }

        public override event PropertyChangedEventHandler PropertyChanged;

        public override void OnPropertyChanged(string propName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }

    }
}
